#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>

#define TASK_NUM 10

typedef void(*task_t)();
task_t tasks[TASK_NUM];

void task1()
{
  printf("这是任务一, pid: %d\n", getpid());
}
void task2()
{
  printf("这是任务二, pid: %d\n", getpid());
}
void task3()
{
  printf("这是任务三, pid: %d\n", getpid());
}

int AddTask(task_t t);

//任务的管理代码
void InitTask()
{
  for (int i = 0; i < TASK_NUM; ++i) tasks[i] = NULL;
  AddTask(task1);
  AddTask(task2);
  AddTask(task3);
}

int AddTask(task_t t)
{
  int pos = 0;
  for (; pos < TASK_NUM; ++pos) {
    if (!tasks[pos]) break;
  }
  if (pos == TASK_NUM) return -1;
  tasks[pos] = t;
  return 0;
}

void DelTask(task_t t)
{

}

void CheckTask()
{

}

void UpdateTask()
{

}

void ExecuteTask()
{
  for (int i = 0; i < TASK_NUM; ++ i) {
    if (!tasks[i])  continue;
    tasks[i]();
  }
}

int main()
{
  pid_t id = fork();
  if (id < 0) {
    perror("fork");
    return 1;
  }
  else if (id == 0) {
    int cnt = 5;
    while (cnt) {
      printf("I am child, pid: %d, ppid: %d, cnt: %d\n",getpid(),getppid(),cnt);
      cnt--;
      sleep(1);
    }
    exit(11);
  }
  else  {
    int status = 0;
    InitTask();
    // pid_t ret = wait(NULL);  // wait是等待任一个子进程退出，若没有则主进程处于阻塞状态；
    // pid_ t ret = waitpid(id,%status,0);  // 第三个参数，若为0则和wait一样；若为WNOHANG则为非阻塞；
    while (1) {   // 轮询
      pid_t ret = waitpid(id, &status, WNOHANG);  // 非阻塞
      if (ret > 0)  {
        if (WIFEXITED(status)) {
          printf("进程是正常跑完的，退出码: %d\n",WEXITSTATUS(status));
        }
        else {
          printf("进程出现异常了\n");
        }
        break;
      }
      else if(ret < 0) {
        printf("wait failed!\n");
        break;
      }
      else {
        ExecuteTask();
        usleep(500000);
      }
    }
  }
  return 0;
}
